#include <stdio.h>
#include <stdlib.h>
#include "API/APICamion.h"
#include <iostream>
#include <list>

int procesarArgumentos(int argc, char *argv[], int *nroCamion);
void mostrarError(int nroCamion);

using namespace std;

int main(int argc, char* argv[])
{	
	int nroCamion = 0;
	long idPersona;
	int error = 0;
	list<long> listaPersonasEnCamion;
	bool salaLiberada = false;
	//char buffer[100];

	
	if (procesarArgumentos(argc, argv, &nroCamion)) {
		exit(1);
	}

	APICamion api = APICamion();
	srand(getpid());	
	
	while (1)
	{
		// En cada vuelta se debe poner a esta variable en cero para que en la
		// próxima vuelta, no se tome que la sala ya está liberada
		salaLiberada = false;
		
		api.ingresarEnSala(nroCamion, &error);
		if (error == ZIPC_FAILURE) {
			mostrarError(nroCamion);
			return 1;
		}		
		
		do {
			// Voy subiendo gente al micro
			idPersona = api.subirPersona(nroCamion, &salaLiberada, &error);
			if (error == ZIPC_FAILURE) {
				mostrarError(nroCamion);
				return 1;
			}
			
			listaPersonasEnCamion.push_back(idPersona);
		} while(salaLiberada == false && listaPersonasEnCamion.size() < TRUCK_CAPACITY);
		

		if (listaPersonasEnCamion.size() == TRUCK_CAPACITY && salaLiberada == false) {
			// Sólo en el caso de que el camión haya salido porque no estaba la sala 
			// vacía, el camión tiene que "manualmente" liberar la sala
			api.abandonarSala(nroCamion, &error);
			if (error == ZIPC_FAILURE) {
				mostrarError(nroCamion);
				return 1;
			}
		}	
		
		// TODO: Simulo el paseo en el camión con un sleep
		sleep(rand() % 10 + 5);
		
		
		do {
			// Terminé el recorrido, voy bajando a la gente del camión
			idPersona = listaPersonasEnCamion.front();
			listaPersonasEnCamion.pop_front();
		
			api.bajarPersona(nroCamion, idPersona, &error);
			if (error == ZIPC_FAILURE) {
				mostrarError(nroCamion);
				return 1;
			}
		} while(listaPersonasEnCamion.size() != 0);
	}
		
	return 0;	
}

int procesarArgumentos(int argc, char *argv[], int *nroCamion) {
	char buffer[100];

	if (argc != 2)
	{
		sprintf(buffer, "Camion - Error: Cantidad de argumentos pasados al programa incorrectos\n");
		write(fileno(stdout), buffer, strlen(buffer));
		return -1;
	}
	
	sscanf(argv[1], "%d", nroCamion); 
	if (*nroCamion < 1)
	{
		sprintf(buffer, "Camion - Error: El identificador de camion debe ser un numero mayor o igual a 1\n");
		write(fileno(stdout), buffer, strlen(buffer));
		return -2;
	}

	return 0;
}

void mostrarError(int nroCamion)
{
	char buffer[100];
	sprintf(buffer, "Camion %d: %s\n", nroCamion, strerror(errno));
	write(fileno(stderr), buffer, strlen(buffer));
}
